package org.grid.model.reader;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Classe responsável pela leitura dos LOG's do sistema
 * @author wellington
 */
public class LogReader {

    // <editor-fold desc="constants">
    /**
     * Valor do eixo X do LOG
     */
    public static final String X_VALUE = "X_Value";
    /**
     * valor do eixo Y do LOG
     */
    public static final String Y_VALUE = "Time";
    // </editor-fold>

    // <editor-fold desc="attributes">
    private String filename;
    private BufferedReader reader;
    private FileReader fileReader;
    private boolean firstLine;
    private boolean lastLine;
    private String[] headers;
    private long lastOperationMilis;
    // </editor-fold>

    ///<editor-fold desc="constructor">
    public LogReader(String filename) throws FileNotFoundException {
        this.filename = filename;
        fileReader = new FileReader(filename);
        reader = new BufferedReader(fileReader);
        headers = findHeaders();
        firstLine = false;
    }
    ///</editor-fold>

    ///<editor-fold desc="getters/setters">
    public String[] getHeaders() {
        return headers;
    }

    public long getLastOperationMilis() {
        return lastOperationMilis;
    }

    public String getFilename() {
        return filename;
    }
    ///</editor-fold>

    ///<editor-fold desc="métodos públicos">
    /**
     * Obtém um certo numero de linhas do LOG
     * @param numLines número de linhas a serem retornadas
     * @return uma lista com as linhas lidas
     */
    public List<String[]> getLines(int numLines) {
        List<String[]> lines = new ArrayList<String[]>();
        for (int x = 0; x < numLines; x++) {
            String[] line = getLine();
            if (line == null || line.length == 0) {
                break;
            }
            lines.add(line);
        }
        return lines;
    }

    /**
     * Verifica se ainda há linhas no arquivo
     * @return sucesso se houver linhas a serem lidas
     */
    public boolean hasNext() {
        return !lastLine;
    }

    /**
     * Obtém os cabeçalhos do arquivo de LOG
     * @return retorna o cabeçalho
     */
    private String[] findHeaders() {
        lastOperationMilis = System.currentTimeMillis();
        try {
            String text = null;
            boolean header = false;
            while (!header) {
                text = reader.readLine();
                int sIdx = text.indexOf(X_VALUE);
                if (sIdx >= 0) {
                    header = true;
                    String[] h = text.substring(sIdx + X_VALUE.length()).split("\\s");
                    String[] hh = new String[h.length - 1];
                    hh[0] = Y_VALUE;
                    for (int i = 1; i < h.length - 1; i++) {
                        hh[i] = h[i];
                    }
                    return hh;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        lastOperationMilis = System.currentTimeMillis() - lastOperationMilis;
        return new String[0];
    }

    /**
     * Obtém uma linha no arquivo
     * @return a linha lida
     */
    public String[] getLine() {
        lastOperationMilis = System.currentTimeMillis();
        try {
            String text = null;
            while (!firstLine) {
                text = reader.readLine();
                if (text == null) {
                    return null;
                }
                int sIdx = text.indexOf('[');
                if (sIdx >= 0) {
                    //primeira linha
                    firstLine = true;
                    return text.substring(sIdx + 1).split("\\s");
                }
            }
            text = reader.readLine();
            if (text == null) {
                return null;
            }
            int eIdx = text.indexOf(']');
            if (eIdx >= 0) {
                //ultima linha
                lastLine = true;
                return text.substring(0, eIdx).split("\\s");
            } else {
                //meio do texto
                return text.split("\\s");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        lastOperationMilis = System.currentTimeMillis() - lastOperationMilis;
        return new String[0];
    }
    ///</editor-fold>
}
